/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import { isArray } from 'lodash';
import { useEffect, useMemo } from 'react';
import { useLocation, useModel } from 'umi';
import { enableRedPointMap } from '.';
import { checkPermissions } from '@/components/Authorized/CheckPermissions';
import { getAuthorityByPathname } from '@/components/PageTabs/_utils';
import { getAuthority } from '@/utils/authority';
import { useInterval } from 'ahooks';

export interface CheckOptions {
  pathname?: string;
  type?: string;
}

type Refresh = (opts?: CheckOptions) => void;

// 是否在请求中
const checkRequestLoadingMap: { [k: string]: boolean } = {};

/**
 *
 * @description 检查红点
 */
export function useCheck(opts: CheckOptions): [boolean, Refresh] {
  const location = useLocation();
  const { pathname = location.pathname, type } = opts;
  const { data, update } = useModel('red-point');

  /**
   *
   * @description 是否有红点
   * data = {[pathname]:type[]}
   */
  const hasRed = useMemo<boolean>(() => {
    const list = data[pathname];
    if (!isArray(list) || list.length === 0) return false;
    if (!type) {
      // 大类目，子类目任何一项有未读的，都返回true
      return true;
    }
    return list.includes(type);
  }, [data, pathname, type]);

  /**
   *
   * @description 触发请求检查是否有红点
   * @param o
   * @param triggerWithType
   * 1、是否依赖type触发更新红点逻辑；
   * 2、且依赖type时，无视checkRequestLoadingMap，强制刷新红点逻辑；
   */
  function trigger(o: CheckOptions, triggerWithType?: boolean) {
    const { pathname: p = pathname, type: t } = o;
    if (!p) return;
    // 依赖type时，保证type存在
    if (triggerWithType && !t) return;
    let enableRedPointCurrent = enableRedPointMap[p];
    if (enableRedPointCurrent) {
      // 判断是否有权限，以及该项是否已经在加载中
      if (
        (checkRequestLoadingMap[p] && !triggerWithType) ||
        !checkPermissions(getAuthorityByPathname(pathname), getAuthority(), true, false)
      )
        return;
      // 批量请求获取是否有待处理数据
      checkRequestLoadingMap[p] = true;
      const redDotData = {};
      if (triggerWithType) {
        // 依赖type时，按照type过滤红点请求列表
        enableRedPointCurrent = enableRedPointCurrent.filter((item) => item.key === t);
      }
      Promise.all(
        enableRedPointCurrent.map((item) =>
          item.request(refresh, { pathname: p, type: item.key }).then((res) => {
            let add = '';
            let remove = '';
            if (res) {
              add = item.key;
            } else {
              remove = item.key;
            }
            return {
              add,
              remove,
            };
          }),
        ),
      )
        .then((res) => {
          const add: string[] = [];
          const remove: string[] = [];
          res.forEach((item) => {
            add.push(item.add);
            remove.push(item.remove);
          });
          redDotData[p] = {
            add,
            remove,
          };
          update(redDotData);
        })
        .finally(() => {
          delete checkRequestLoadingMap[p];
        });
    }
  }

  /**
   *
   * @description 刷新
   * 采用统一方案，将refresh缓存到对应service/request上，之后在service触发后调用
   * @param o
   */
  function refresh(o: CheckOptions = opts) {
    return trigger(o, true);
  }

  useEffect(() => {
    if (!pathname) return;
    trigger({ pathname, type });
  }, [pathname, type]);

  // 循环刷新，暂定每3分钟
  const clearInterval = useInterval(() => {
    if (type) return;
    trigger({ pathname, type });
  }, 3 * 60 * 1000);

  useEffect(() => {
    return clearInterval;
  }, []);

  return [hasRed, refresh];
}
